package panda.file;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import panda.server.Panda;

public class Page {
	public static final int BLOCK_SIZE = Block.BLOCK_SIZE;

	/**
	 * The size of an integer, in BYTE
	 */
	// TODO Please modify this to the correct value
	public static int INT_SIZE = Integer.SIZE / Byte.SIZE;

	/**
	 * The size of a float, in BYTE
	 */
	// TODO Please modify this to the correct value
	public static int FLOAT_SIZE = Float.SIZE / Byte.SIZE;

	public static int LONG_SIZE = Long.SIZE / Byte.SIZE;

	public static int STR_SIZE(String string) {
		int bytesPerChar = (int) Charset.defaultCharset().newEncoder()
		.maxBytesPerChar();
		return INT_SIZE + string.length() * bytesPerChar;
	}

	public static int STR_SIZE(int length) {
		int bytesPerChar = (int) Charset.defaultCharset().newEncoder()
		.maxBytesPerChar();
		return INT_SIZE + length * bytesPerChar;
	}

	public static int ARRAY_SIZE(byte[] array) {
		return INT_SIZE + array.length;
	}

	private ByteBuffer contents = ByteBuffer.allocateDirect(Block.BLOCK_SIZE);

	private FileManager fileManager = Panda.getFileManager();

	public synchronized int read(Block block) {
		return fileManager.read(block, contents);
	}

	public synchronized int write(Block block) {
		return fileManager.write(block, contents);
	}

	public synchronized Block append(String fileName) {
		return fileManager.append(fileName, contents);
	}

	public synchronized int getInt(int offset) {
		//System.out.println("offset " + offset);
		int value = contents.getInt(offset);
		//		if (offset == 0)
		//			System.out.println(this + "GET [" + offset + "] to " + value);
		return value;
	}

	public synchronized void putInt(int offset, int value) {
		contents.putInt(offset, value);
		//		if (offset == 0 && (value == 47 || value == 95)) {
		//			System.out.println(this + "SET [" + offset + "] to " + value);
		//		}
	}

	public synchronized float getFloat(int offset) {
		return contents.getFloat(offset);
	}

	public synchronized void putFloat(int offset, float value) {
		contents.putFloat(offset, value);
	}

	public synchronized long getLong(int offset) {
		return contents.getLong(offset);
	}

	public synchronized void putLong(int offset, long value) {
		contents.putLong(offset, value);
	}

	public synchronized byte[] getArray(int offset) {
		contents.position(offset);
		int length = contents.getInt();
		byte[] returnValue = new byte[length];
		contents.get(returnValue, 0, length);
		return returnValue;
	}

	public synchronized byte[] getArray(int offset,int length) {
		contents.position(offset);
		byte[] returnValue = new byte[length];
		contents.get(returnValue, 0, length);
		return returnValue;
	}
	
	public synchronized void putArray(int offset, byte[] value) {
		contents.position(offset);
		contents.putInt(value.length);
		contents.put(value);
	}

	public synchronized String getString(int offset) {
		contents.position(offset);
		int length = contents.getInt();
		byte[] byteArray = new byte[length];
//		if (offset == 179) {
//			System.out.println(this);
//			System.out.println("OFFSET = " + offset);
//			System.out.println("LENGTH = " + byteArray.length + "\n");
//		}
		contents.get(byteArray, 0, byteArray.length);
		return new String(byteArray);
	}

	public synchronized void putString(int offset, String value) {
		contents.position(offset);
		contents.putInt(value.getBytes().length);
		contents.put(value.getBytes());
//		if (offset % 2 == 1 && offset > 100) {
//			System.out.println(this);
//			System.out.println(offset + " : " + value + "\n");
//		}
//		System.out.println(this + " SET [" + offset + "] to " + value);
	}
	
	public synchronized void memCpy(int fromPosition,int toPosition,int length){
		byte[] temp = new byte[length];
		contents.position(fromPosition);
		contents.get(temp,0,length);
		contents.position(toPosition);
		contents.put(temp,0,length);
	}


}
